package com.example.gobang.game;

import com.example.gobang.model.MatchResponse;
import com.example.gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

@Component
@Slf4j
public class Matcher {
    @Autowired
    private OnlineUserManager userManager;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RoomManager roomManager;

    private final Queue<User> nomalQueue = new LinkedList<>();
    private final Queue<User> highQueue = new LinkedList<>();
    private final Queue<User> veryHighQueue = new LinkedList<>();

    public void add(User user){
        // 玩家点击开始匹配 加入到匹配队列中
        if(user.getScore() < 2000){
            synchronized (nomalQueue) {
                nomalQueue.offer(user);
                nomalQueue.notify();
            }
            log.info("玩家: {} 加入到了 normalQueue 中", user.getUsername());
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.offer(user);
                highQueue.notify();
            }
            log.info("玩家: {} 加入到了 highQueue 中", user.getUsername());
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            log.info("玩家: {} 加入到了 veryHighQueue 中", user.getUsername());
        }
    }

    public void remove(User user){
        // 玩家点击停止匹配 从匹配队列中移除
        if(user.getScore() < 2000){
            synchronized (nomalQueue) {
                nomalQueue.remove(user);
            }
            log.info("玩家: {} 从 normalQueue 中移除", user.getUsername());
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.remove(user);
            }
            log.info("玩家: {} 从 highQueue 中移除", user.getUsername());
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.remove(user);
            }
            log.info("玩家: {} 从 veryHighQueue 中移除", user.getUsername());
        }
    }

    public Matcher(){
        Thread t1 = new Thread(() -> {
            while (true){
                handlerMatch(nomalQueue);
            }
        });
        t1.start();
        Thread t2 = new Thread(() -> {
            while (true){
                handlerMatch(highQueue);
            }
        });
        t2.start();
        Thread t3 = new Thread(() -> {
            while (true){
                handlerMatch(veryHighQueue);
            }
        });
        t3.start();
    }

    public void handlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue) {
            try {
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                log.info("匹配成功: 玩家1 {} 和 玩家2 {} 的对战", player1.getUsername(), player2.getUsername());
                // 获取到websocket的会话
                WebSocketSession session1 = userManager.getOnline(player1.getUserId());
                WebSocketSession session2 = userManager.getOnline(player2.getUserId());

                if (session1 == null) {
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null) {
                    matchQueue.offer(player1);
                    return;
                }
                if (session1 == session2) {
                    matchQueue.offer(player1);
                    return;
                }

                // 把玩家放入到一个游戏房间中
                Room room = new Room();
                roomManager.add(room, player1.getUserId(), player2.getUserId());


                // 为两个玩家都返回响应
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                String json1 = objectMapper.writeValueAsString(response1);
                session1.sendMessage(new TextMessage(json1));

                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                String json2 = objectMapper.writeValueAsString(response2);
                session2.sendMessage(new TextMessage(json2));
            } catch (IOException | InterruptedException e) {
                log.error("", e);
            }
        }
    }
}
